package com.szl.group.template;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.function.Supplier;

@Slf4j
@Service
public class ServiceExecuteTemplateImpl implements ServiceExecuteTemplate {

    @Autowired
    private TransactionTemplate transactionTemplate;

    /**
     * 不在事务里执行
     *
     * @param process
     * @param <T>
     * @return
     */
    @Override
    public <T> Result<T> doWithoutTransaction(Process<T> process) {
        try {
            //前置操作：参数校验
            process.before();
            //执行
            T data = process.execute();
            //后置操作
            process.after();
            //返回结果
            return ResultUtils.buildSuccess(data);
        } catch (TrustException e) {
            return ResultUtils.buildFailed(e.getErrorCode(), e.getErrorMsg(), e.getData());
        } catch (IllegalArgumentException e) {
            return ResultUtils.buildFailed(ResultCodeEnum.ILLEGAL_PARAM.getCode(), e.getMessage());
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
            return ResultUtils.buildFailed(ResultCodeEnum.THROWABLE_EXPECTION);
        }
    }


    /**
     * 在事务里执行 不带前置和后置
     *
     * @param process
     * @param <T>
     * @return
     */
    @Override
    public <T> Result<T> doInTransaction(Process<T> process) {
        try {
            return transactionTemplate.execute(transactionStatus -> {
                //前置操作：参数校验
                process.before();
                //执行
                T data = process.execute();
                //后置操作
                process.after();
                //返回结果
                return ResultUtils.buildSuccess(data);
            });
        } catch (TrustException e) {
            return ResultUtils.buildFailed(e.getErrorCode(), e.getErrorMsg(), e.getData());
        } catch (IllegalArgumentException e) {
            return ResultUtils.buildFailed(ResultCodeEnum.ILLEGAL_PARAM.getCode(), e.getMessage());
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
            return ResultUtils.buildFailed(ResultCodeEnum.THROWABLE_EXPECTION);
        }
    }

    @Override
    public <T> Result<T> doWithoutTransactionL(Supplier<T> process) {

        try {

            //执行
            T data = process.get();

            return ResultUtils.buildSuccess(data);
        } catch (TrustException e) {
            return ResultUtils.buildFailed(e.getErrorCode(), e.getErrorMsg(), e.getData());
        } catch (IllegalArgumentException e) {
            return ResultUtils.buildFailed(ResultCodeEnum.ILLEGAL_PARAM.getCode(), e.getMessage());
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
            return ResultUtils.buildFailed(ResultCodeEnum.THROWABLE_EXPECTION);
        }
    }

    @Override
    public <T> Result<T> doInTransactionL(Supplier<T> process) {
        try {
            return transactionTemplate.execute(transactionStatus -> {

                //执行
                T data = process.get();

                return ResultUtils.buildSuccess(data);
            });
        } catch (TrustException e) {
            return ResultUtils.buildFailed(e.getErrorCode(), e.getErrorMsg(), e.getData());
        } catch (IllegalArgumentException e) {
            return ResultUtils.buildFailed(ResultCodeEnum.ILLEGAL_PARAM.getCode(), e.getMessage());
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
            return ResultUtils.buildFailed(ResultCodeEnum.THROWABLE_EXPECTION);
        }
    }
}
